package com.example.springboot.config;

import com.example.springboot.converter.XiaoGangMessageConverter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.accept.HeaderContentNegotiationStrategy;
import org.springframework.web.accept.ParameterContentNegotiationStrategy;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.*;

/**
 * web 的配置类
 *
 * @author by Mr. Li 2021/1/31 15:41
 */
@Configuration
@Slf4j
public class MyWebConfig {

    /**
     * 定一只Spring MVC 功能
     *
     * @return WebMvcConfigurer
     */
    @Bean
    public WebMvcConfigurer webMvcConfigurer() {
        return new WebMvcConfigurer() {


            /**
             *  添加一个自定义的内容协商策略
             * @param configurer configurer
             */
            @Override
            public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
                // 添加基于请求参数的 媒体类型
                //(Map<String, MediaType> mediaTypes 参数，说明了，我们可以进行自定义的映射关系
                Map<String, MediaType> mediaTypes = new HashMap<>();
                mediaTypes.put("json", MediaType.APPLICATION_JSON);
                mediaTypes.put("xml", MediaType.APPLICATION_XML);
                mediaTypes.put("xg", MediaType.parseMediaType(XiaoGangMessageConverter.xiaogangFormat));
                final ParameterContentNegotiationStrategy parameterStrategy = new ParameterContentNegotiationStrategy(mediaTypes);
                parameterStrategy.setParameterName("_p"); // 还可以更改 参数名称
                // 自定义 策略之后，会导致原来默认添加进入的策略会丢失。所以这里需要手动设置一下。
                // 基于这种特性，我们可以完全自己手写一个ContentNegotiationStrategy
                final HeaderContentNegotiationStrategy headerStrategy = new HeaderContentNegotiationStrategy();

                configurer.strategies(Arrays.asList(parameterStrategy, headerStrategy));
            }

            /**
             *  这个是 覆盖 原容器中WebMvcConfigurer configureMessageConverters 的功能
             * @param converters converters
             */
            @Override
            public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
            }

            /**
             * 对原容器中 MessageConverter 进行增强，扩展
             * @param converters converters
             */
            @Override
            public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
                log.debug(">>>>>>>>>>>>>> add custom converter <<<<<<<<<<<<<<<<<<<<<");
                converters.add(new XiaoGangMessageConverter());
            }
        };
    }
}
